#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

#define N 10
#define M 10

// 人 'X' ; 终点 '@' ; 箱子 '*' ; 障碍物 '#' ; 空地 '.'
char Maze[N][M];

bool visited[N][M][N][M];
// 地图大小
int n, m;

struct Node
{
    int man_x, man_y, box_x, box_y;
    int length;
};

Node Init()
{
    cout << "请输入地图大小：NxM" << endl;
    cin >> n >> m;
    Node start;

    cout << "请输入地图数据：" << endl;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
        {
            char ch;
            cin >> ch;
            Maze[i][j] = ch;

            if (ch == '*')
                start.box_x = i, start.box_y = j;
            else if (ch == 'X' || ch == 'x')
                start.man_x = i, start.man_y = j;
        }

    start.length = 0;
    return start;
}

int Min_step(const Node &start)
{
    visited[start.man_x][start.man_y][start.box_x][start.box_y] = true;

    queue<Node> q;
    q.push(start);
    while (!q.empty())
    {
        Node curr = q.front();
        q.pop();

        if (Maze[curr.box_x][curr.box_y] == '@')
            return curr.length;

        // 上下左右四个方向
        for (int k = 0; k < 4; k++)
        {
            int next_man_x = curr.man_x + ((k == 0) ? -1 : ((k == 1) ? 1 : 0));
            int next_man_y = curr.man_y + ((k == 2) ? -1 : ((k == 3) ? 1 : 0));
            int next_box_x = curr.box_x;
            int next_box_y = curr.box_y;

            // 人触碰边界
            if (next_man_x < 0 || next_man_x >= n || next_man_y < 0 || next_man_y >= m)
                continue;

            // 人触碰障碍物
            if (Maze[next_man_x][next_man_y] == '#')
                continue;

            // 如果人移动后与箱子重合（需要推动箱子）
            if (curr.box_x == next_man_x && curr.box_y == next_man_y)
            {
                next_box_x += ((k == 0) ? -1 : ((k == 1) ? 1 : 0));
                next_box_y += ((k == 2) ? -1 : ((k == 3) ? 1 : 0));

                // 箱子触碰边界
                if (next_box_x < 0 || next_box_x >= n || next_box_y < 0 || next_box_y >= m)
                    continue;

                // 箱子触碰障碍物
                if (Maze[next_box_x][next_box_y] == '#')
                    continue;
            }
            if (visited[next_man_x][next_man_y][next_box_x][next_box_y])
                continue;

            q.push({next_man_x, next_man_y, next_box_x, next_box_y, curr.length + 1});
            visited[next_man_x][next_man_y][next_box_x][next_box_y] = true;
        }
    }

    return -1;
}

/*
4 4
. . . .
. . * @
. . . .
. X . .

6 6
. . . . . .
. . . . . .
# * # # . .
. . # . # .
. . X . . .
. @ # . . .
*/

int main()
{
    memset(visited, 0, sizeof(visited));
    Node start = Init();
    cout << Min_step(start) << endl;
    return 0;
}